/**
 * @fileoverview js.dom.Event class {@link http://jsvm.org/}
 * @file		Event.jsc
 * @based on EventManager.jsc by WanChanghua
 * @modified by	DSONet @23:20 2006-6-24
 * @version	$Id: Event.js 35 2008-03-02 17:01:34Z dsonet $
 */
var Event = new function()
{
	this.on = this.addListener = function(oTarget, sType, fHandle, oScope, bCapture)
	{
		if(isValidCollection(oTarget))
		{
			for(var i = oTarget.length - 1; i >= 0; i--)
			{
				this.on(oTarget[i], sType, fHandle, oScope, bCapture);
			}
			return;
		}
		bCapture = Type.isBoolean(oScope) ? oScope : bCapture == true;

		if (!Type.isObject(oScope))
		{
			oScope = oTarget;
		}
		var ls = (listeners[sType] ? listeners[sType] : listeners[sType] = {})
			, key = Type.hashCode(oTarget) + Type.hashCode(fHandle)
			, wrappedFn = !ls[key]? (ls[key] = createWrappeFn(fHandle, oScope)) : ls[key];

		if(extras[sType])
			return extras[sType].add(ls[key], bCapture);

		//logger.debug(oTarget+"对象注册了事件处理器KEY值"+key);

		if (oTarget.attachEvent)
		{
			oTarget.attachEvent("on" + sType, wrappedFn);

			if (bCapture && oTarget.setCapture)
			{
				oTarget.setCapture();
			}
		}
		else if (oTarget.addEventListener)
		{
			oTarget.addEventListener(sType, wrappedFn, bCapture);
		}
		else
		{
			var fn = oTarget["on" + sType];
			if(typeof fn == "function")
				return (oTarget["on" + sType] =	createWrappeFn2(fn, wrappedFn));
			oTarget["on" + sType] = wrappedFn;
		}
	}
	this.un = this.removeListener = function(oTarget, sType, fHandle, bCapture)
	{
		if(isValidCollection(oTarget))
		{
			for(var i = oTarget.length - 1; i >= 0; i--)
			{
				this.un(oTarget[i], sType, fHandle, bCapture);
			}
			return;
		}
		var key = Type.hashCode(oTarget) + Type.hashCode(fHandle);

		if (!listeners[sType] || !listeners[sType][key])
			return;

		Type.hashCode(oTarget, -1);
		Type.hashCode(fHandle, -1);
		var wrappedFn = listeners[sType][key];
		bCapture = (bCapture == true);

		if (oTarget.detachEvent)
		{
			oTarget.detachEvent("on" + sType, wrappedFn);

			if (bCapture && oTarget.releaseCapture)
			{
				oTarget.releaseCapture();
			}
		}
		else if (oTarget.removeEventListener)
		{
			oTarget.removeEventListener(sType, wrappedFn, bCapture);
		}
		else
		{
			try
			{
				delete el["on" + evname];
			}
			catch (ex)
			{
				el["on" + evname] = null;
			}
		}

		delete listeners[sType][key];

		for (var _ in listeners[sType])
			return;

		delete listeners[sType];
	}
	this.stop = function(ev)
	{
		ev = this.getEvent(ev);

		if(ev)
		{
			if(typeof ev.preventDefault == "function")
			{
				ev.preventDefault();
				ev.stopPropagation();
			}
			else
			{
				ev.cancelBubble = true;
				ev.returnValue = false;
			}
		}
	}

	this.cancel = function(ev)
	{
		ev = this.getEvent(ev);

		if(ev)
		{
			if(typeof ev.preventDefault == "function")
			{
				ev.preventDefault();
			}
			else
			{
				ev.returnValue = false;
			}
		}
	};

	this.getTarget = function(ev)
	{
		ev = this.getEvent(ev);

		if(!ev)
			return null;

		var el = ev.srcElement || ev.target;

		if(!el)
			return null;

		while (el && el.nodeType != 1) // climb up from text nodes on Moz
		{
			el = el.parentNode;
		}

		return el;
	}

	this.getEvent = function (ev)
	{
		return ev || window.event;
	}
	/**
	 * We want to be able to use getElementsByTagName as a collection
	 * to attach a group of events to.  Unfortunately, different 
	 * browsers return different types of collections.  This function
	 * tests to determine if the object is array-like.  It will also 
	 * fail if the object is an array, but is empty.
	 * @method isValidCollection
	 * @param o the object to test
	 * @return {boolean} true if the object is array-like and populated
	 * @static
	 * @private
	 */
	function isValidCollection(o)
	{
		return ( o                    && // o is something
				 o.length             && // o is indexed
				 typeof o != "string" && // o is not a string
				 !o.tagName           && // o is not an HTML element
				 !o.alert             && // o is not a window
				 typeof o[0] != "undefined" );

	}
	function createWrappeFn(fHandle, oScope)
	{
		return function(oEvent)
		{
			return fHandle.call(oScope, (IEFormatEvent(oEvent || window.event)));
		}
	}
	function createWrappeFn2(fHandle1, fHandle2)
	{
		return function()
		{
			fHandle1();
			fHandle2();
		}
	}
	function IEFormatEvent(event){
		if(event && !event.stopPropagation){
			event.timeStamp = (new Date).getTime();
			event.target = event.srcElement;
			event.charCode = (event.type == "keypress") ? event.keyCode : 0;
			event.eventPhase = 2;
			event.isChar = event.charCode > 0;

			event.pageX = event.clientX + parseInt(document.body["scrollLeft"]||document.documentElement["scrollLeft"], 10);
			event.pageY = event.clientY + parseInt(document.body["scrollTop"]||document.documentElement["scrollTop"], 10);

			event.relatedTarget = event.type == "mouseout" ? event.toElement : event.type == "mouseover" ? event.fromElement : null;

			event.preventDefault = IEEventPreventDefault;
			event.stopPropagation = IEEventStopPropagation;
		}
		return event;
	}

	function IEEventStopPropagation() {
		this.cancelBubble = true;
	}

	function IEEventPreventDefault() {
		this.returnValue = false;
	}

	var listeners = {};
};

var extras = new function() {
	var drl =[];
	this.loaded = false;
	this.domready = function()
	{
		if(drl == null)
			return;
		for (var i = 0; i < drl.length; i++)
		{
			drl[i]();
			delete drl[i];
		}
		drl = null;
		extras.loaded = true;
	}
	this.domready.add = function(ls, runIt)
	{
		if(!($JSI.loaded || extras.loaded))
			drl.push(ls);
		else if(runIt)
			ls();
	}
};


if(!($JSI.loaded || extras.loaded)){
	if (System.isIE())
	{
		//for IE5 DOMReady Support
		var def = "ie_domready" + System.GUID();
		document.write("<scr"+"ipt id='"+ def  +"' type='text/javascript' defer='defer' src='/" + "/:'></scr"+"ipt>");
		// Use the defer script hack
		var el = document.getElementById(def);
		el.removeAttribute("id");
		def = null;
		// script does not exist if jQuery is loaded dynamically
		if (el.readyState == "complete")
		{
			el.parentNode.removeChild(el);
			extras.domready();
		}
		else
		{
			el.onreadystatechange = function()
			{
				if (this.readyState == "complete")
				{
					this.parentNode.removeChild(this);
					extras.domready();
				}
			};
		}
		el = null;
	}
	else if (System.isGecko(20020826))// || System.isOpera(9)
	{
		//Mozilla 1.0.1 支持 DOMContentLoaded
		Event.on(document, "DOMContentLoaded", extras.domready);
	}
	else
	{
		if (document.readyState)
		{
			var timer = setInterval(function()
			{
				if ("loaded,complete".indexOf(document.readyState))
				{
					window.clearInterval(timer);
					timer = null;
					extras.domready();
				}
			}, 10);
		}
		Event.on(window, "load", extras.domready);
	}
}